package io.renren.modules.generator.controller;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.renren.common.enums.FileStatus;
import io.renren.common.exception.RRException;
import io.renren.common.utils.ShiroUtils;
import io.renren.modules.generator.constant.UrlConstant;
import io.renren.modules.generator.entity.MkdirEntity;
import io.renren.modules.generator.service.MkdirService;
import io.renren.modules.generator.vo.FileVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.renren.modules.generator.entity.FileEntity;
import io.renren.modules.generator.service.FileService;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;


/**
 * @author jianzhen
 * @email sunlightcs@gmail.com
 * @date 2022-03-14 22:03:11
 */
@RestController
@RequestMapping("generator/file")
@Transactional
@Slf4j
public class FileController {
    @Autowired
    private FileService fileService;

    @Autowired
    private MkdirService mkdirService;

    /**
     * 正常文件列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params) {
        params.put("userId", ShiroUtils.getUserId());
        Page<Map<String, Object>> page = new Page<>(Long.valueOf(String.valueOf(params.get("page"))), Long.valueOf(String.valueOf(params.get("limit"))));
        IPage<Map<String, Object>> mapIPage = fileService.selectFileList(page, params);
        PageUtils newPage = new PageUtils(mapIPage);
        return R.ok().put("page", newPage);
    }

    /**
     * 收藏文件列表
     */
    @RequestMapping("/restorList")
    public R restorList(@RequestParam Map<String, Object> params) {
        params.put("userId", ShiroUtils.getUserId());
        Page<Map<String, Object>> page = new Page<>(Long.valueOf(String.valueOf(params.get("page"))), Long.valueOf(String.valueOf(params.get("limit"))));
        IPage<Map<String, Object>> mapIPage = fileService.selectRestoreFileList(page, params);
        PageUtils newPage = new PageUtils(mapIPage);
        return R.ok().put("page", newPage);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{fileId}")
    public R info(@PathVariable("fileId") Integer fileId) {
        FileEntity file = fileService.getById(fileId);

        return R.ok().put("file", file);
    }

    /**
     * 收藏文件
     *
     * @param fileId
     * @return
     */
    @RequestMapping("/restore/{id}")
    public R restore(@PathVariable("id") Integer fileId) {
        UpdateWrapper<FileEntity> wrapper = new UpdateWrapper<>();
        wrapper.set("is_restore", FileStatus.RESTORE.getStatus());
        wrapper.eq("file_id", fileId);
        fileService.update(wrapper);

        return R.ok();
    }

    /**
     * 取消收藏文件
     *
     * @param fileId
     * @return
     */
    @RequestMapping("/cancelRestore/{id}")
    public R cancelRestore(@PathVariable("id") Integer fileId) {
        UpdateWrapper<FileEntity> wrapper = new UpdateWrapper<>();
        wrapper.set("is_restore", FileStatus.NORESTORE.getStatus());
        wrapper.eq("file_id", fileId);
        fileService.update(wrapper);

        return R.ok();
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody FileEntity file) {
        //设置文件为未删除
        file.setIsDelete(FileStatus.NORMAL.getStatus());
        String realName = file.getRealName();
        String beforeFile = UrlConstant.dirUrl + realName;
        String prefix = UrlConstant.fileUrl;
        if (Objects.nonNull(file.getDirId())) {
            MkdirEntity mkdirEntity = mkdirService.getById(file.getDirId());
            prefix = mkdirEntity.getDirUrl() + "/";
            String localFile = mkdirEntity.getLocalDir() + "/" + realName;
            try {
                Files.move(Paths.get(beforeFile), Paths.get(localFile));
            } catch (Exception e) {
                log.error("文件移动失败", e);
                throw new RRException("文件转移失败");
            }
        }
        file.setFileUrl(prefix + realName);
        //设置文件创建时间
        file.setCreateTime(new Date());
        //设置创建文件用户
        file.setUserId(ShiroUtils.getUserId());

        fileService.save(file);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody FileEntity file) {
        String realName = file.getRealName();
        String beforeFile = UrlConstant.dirUrl + realName;
        String nowFileUrl = "";
        if (Objects.nonNull(file.getDirId())) {
            MkdirEntity mkdirEntity = mkdirService.getById(file.getDirId());
            String fileUrl = mkdirEntity.getDirUrl() + "/" + realName;
            nowFileUrl = mkdirEntity.getLocalDir() + "/" + realName;
            file.setFileUrl(fileUrl);
        }
        if (StringUtils.isNotBlank(nowFileUrl)) {
            try {
                Files.move(Paths.get(beforeFile), Paths.get(nowFileUrl));
            } catch (IOException e) {
                log.error("文件移动失败", e);
                throw new RRException("文件转移失败");
            }
        }
        fileService.updateById(file);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete/{id}")
    public R delete(@PathVariable("id") Integer fileId) {
        FileEntity fileEntity = new FileEntity();
        fileEntity.setFileId(fileId);
        //设置为删除状态
        fileEntity.setIsDelete(FileStatus.DELETE.getStatus());
        //设置文件删除时间-默认回收时间为一个月
        Date date = new Date();
        //创建Calendar实例
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);   //设置当前时间
        //同理增加一个月和一天的方法：
        cal.add(Calendar.MONTH, 1);
        fileEntity.setDeleteTime(cal.getTime());

        fileService.updateById(fileEntity);

        return R.ok();
    }

    /**
     * 删除文件列表
     */
    @RequestMapping("/deleteList")
    public R deleteList(@RequestParam Map<String, Object> params) {
        params.put("userId", ShiroUtils.getUserId());
        Page<Map<String, Object>> page = new Page<>(Long.valueOf(String.valueOf(params.get("page"))), Long.valueOf(String.valueOf(params.get("limit"))));
        IPage<Map<String, Object>> mapIPage = fileService.selectDeleteFileList(page, params);
        PageUtils newPage = new PageUtils(mapIPage);

        return R.ok().put("page", newPage);
    }

    /**
     * 清空回收站文件
     */
    @RequestMapping("/clear/{id}")
    public R clear(@PathVariable("id") Integer fileId) {
        FileEntity fileEntity = fileService.getById(fileId);
        String url = UrlConstant.dirUrl + fileEntity.getFileUrl().substring(22);
        File file = new File(url);
        file.delete();
        fileService.removeById(fileId);
        return R.ok();
    }

    /**
     * 取回文件
     *
     * @param fileId
     * @return
     */
    @RequestMapping("/reclaim/{id}")
    public R reclaim(@PathVariable("id") Integer fileId) {

        fileService.reclaim(fileId);

        return R.ok();
    }

    /**
     * 获取文件夹下所有文件
     *
     * @param dirId
     * @return
     */
    @RequestMapping("/fileListDir/{id}")
    public R fileListDir(@PathVariable("id") Integer dirId) {

        List<FileEntity> fileEntities = fileService.fileListDir(dirId);

        return R.ok().put("fileList", fileEntities);
    }
}
